package com.learn.eduorder.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.WXPayUtil;
import com.jfinal.kit.HttpKit;
import com.learn.eduapi.entity.ResponseDTO;
import com.learn.eduapi.entity.order.PayOrder;
import com.learn.eduapi.entity.order.PayOrderRecord;
import com.learn.eduapi.entity.order.UserCourseOrder;
import com.learn.educourseboot.service.CourseService;
import com.learn.eduorder.config.PayConfig;
import com.learn.eduorder.service.OrderService;
import jdk.nashorn.internal.ir.annotations.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单模块
 */
@RestController
@CrossOrigin
@RequestMapping("order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Reference
    private CourseService courseService;

    /**
     * 获取课程信息生成微信支付二维码
     * @param courseId
     * @param courseName
     * @param price
     * @return
     */
    @GetMapping("createCode")
    public Object createCode(@RequestParam("courseid") String courseId,
                             @RequestParam("coursename")String courseName,
                             @RequestParam("price") String price) throws Exception {

        System.out.println("courseName = " + courseName);
        System.out.println("price = " + price);
        //1.编写商户信息
        Map<String,String> mm = new HashMap();
        mm.put("appid",PayConfig.appid); //公众账号ID
        mm.put("mch_id",PayConfig.partner);//商户号
        mm.put("nonce_str",WXPayUtil.generateNonceStr());//随机字符串
//        courseName = new String(courseName.getBytes("ISO-8859-1"),"UTF-8");
        mm.put("body",courseName); //商品名称
        String orderId = WXPayUtil.generateNonceStr();
        System.out.println("订单编号 = "+orderId);
        mm.put("out_trade_no",orderId); //商户订单号
        mm.put("total_fee",price+""); //订单金额,单位分
        mm.put("spbill_create_ip","127.0.0.1"); //终端IP
        mm.put("notify_url",PayConfig.notifyurl); //通知地址
        mm.put("trade_type","NATIVE"); //交易类型
        System.out.println("发送的map = "+mm.toString());

        //2.生成数字签名,并把上面的map转换成xml格式
        String xml = WXPayUtil.generateSignedXml(mm,PayConfig.partnerKey);
        System.out.println("转换后的xml = "+xml);

        //3.将数据发送给微信后台,并得到微信后台返回的数据
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String result = HttpKit.post(url,xml);
        System.out.println("返回的xml = "+result); //如果报错：<![CDATA[签名错误]]> 商户四要素的原因，重置商户API密钥。

        //4.后台返回的xml格式，转成map，并添加两个参数
        Map<String,String> resultMap = WXPayUtil.xmlToMap(result);
        resultMap.put("orderId",orderId);
        resultMap.put("money",price+"");

        // 查询订单状态需要订单编号，所以将订单编号保存并返回给前端
        resultMap.put("out_trade_no",mm.get("out_trade_no"));

        System.out.println("=====================================================================");
        System.out.println("resultMap = " + resultMap);
        //5.将map返回给浏览器
        return resultMap;
    }


    /**
     * 微信支付回调
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("wxCallback")
    public String wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inStream = null;
        ByteArrayOutputStream outSteam = null;
        String resultxml = null;
        try {
            inStream = request.getInputStream();
            outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            resultxml = new String(outSteam.toByteArray(), "utf-8");
        } catch (Exception e) {
            System.out.println("回调处理失败");
        }finally {
            if(null != outSteam) {
                outSteam.close();
            }
            if(null != inStream) {
                inStream.close();
            }
        }
        System.out.println("wxCallback - 回调请求参数:"+ resultxml);
        return resultxml;
    }



    /**
     * 检查支付状态
     * @param orderId
     * @return
     */
    @GetMapping("checkOrderStatus")
    public Object checkOrderStatus(@RequestParam("orderId")String orderId)throws Exception{
        //1.编写商户信息
        Map<String,String> mm = new HashMap();
        mm.put("appid",PayConfig.appid); //公众账号ID
        mm.put("mch_id",PayConfig.partner);//商户号
        mm.put("out_trade_no",orderId);//订单编号
        mm.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串
        System.out.println(mm);
        //2.生成数字签名,并把上面的map转换成xml格式
        String xml = WXPayUtil.generateSignedXml(mm, PayConfig.partnerKey);
        System.out.println(xml);

        //3.将数据发送给微信后台,并得到微信后台返回的数据
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";

        //第一次询问时间
        long beginTime = System.currentTimeMillis();

        while(true) { //不停的去微信后台询问是否支付
            String result = HttpKit.post(url, xml);
            System.out.println(result);//报错：<![CDATA[签名错误]]>

            //4.后台返回的xml格式，转成map，并添加两个参数
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);

            //5.将map转成json并返回给浏览器
            //已经成功支付，停止询问
            if(resultMap.get("trade_state").equalsIgnoreCase("success")){
                System.out.println("支付成功");

                return resultMap;
            }
            //超过30秒未支付，停止询问
            if(System.currentTimeMillis() - beginTime > 30000){
                return resultMap;
            }
            Thread.sleep(3000); //每隔3秒，询问一次微信后台
        }
    }

    /**
     * 保存订单
     * @param orderNo
     * @param userId
     * @param courseId
     * @param activityCourseId
     * @param sourcetype
     * @param price
     * @return
     */
    @GetMapping("saveOrder")
    public ResponseDTO<UserCourseOrder> saveOrder(@RequestParam("orderNo")String orderNo,
                                                  @RequestParam("user_id")String userId,
                                                  @RequestParam("course_id")String courseId,
                                                  @RequestParam("activity_course_id")String activityCourseId,
                                                  @RequestParam("source_type")String sourcetype,
                                                  @RequestParam("price")Integer price
                                                  ){

         //订单表
        UserCourseOrder userCourseOrder = new UserCourseOrder();
        userCourseOrder.setOrderNo(orderNo);
        userCourseOrder.setUserId(userId);
        userCourseOrder.setCourseId(courseId);
        userCourseOrder.setActivityCourseId(Integer.parseInt(activityCourseId));
        userCourseOrder.setSourceType(sourcetype);
        int insert = orderService.insertOrder(userCourseOrder);

        //日志表
        PayOrderRecord payOrderRecord = new PayOrderRecord();
        payOrderRecord.setOrderNo(orderNo);
        payOrderRecord.setType("CREATE");
        payOrderRecord.setFromStatus("0");
        payOrderRecord.setToStatus("已创建");
        payOrderRecord.setPaidAmount(price);
        payOrderRecord.setCreatedBy(userId);
        int i = orderService.insertPayOrderRecord(payOrderRecord);
        ResponseDTO<UserCourseOrder> responseDTO = new ResponseDTO<>();
        responseDTO.setState(200);
        responseDTO.setMessage("保存订单成功");
        return responseDTO;
    }

    /**
     * 更新订单的状态
     * @param orderNo
     * @param status
     * @param userId
     * @param courseId
     * @param courseName
     * @param price
     * @return
     */
    @GetMapping("updateOrder")
    public ResponseDTO<UserCourseOrder> updateOrder(@RequestParam("orderNo")String orderNo,
                                                    @RequestParam("status")String status,
                                                    @RequestParam("user_id")String userId,
                                                    @RequestParam("course_id")String courseId,
                                                    @RequestParam("course_name")String courseName,
                                                    @RequestParam("price")String price
    ) {
        System.out.println("==============================================更新订单的状态=======================================");
        System.out.println("==============================================更新订单的状态=======================================");
        System.out.println("==============================================更新订单的状态=======================================");
        System.out.println("==============================================更新订单的状态=======================================");
        System.out.println("userId = " + userId);
        //支付订单表
        PayOrder payOrder = new PayOrder();
        payOrder.setOrderNo(orderNo);
        payOrder.setUserId(userId);
        payOrder.setProductId(courseId);
        payOrder.setProductName(courseName);
        payOrder.setAmount(Double.parseDouble(price));
        payOrder.setCount(1);
        payOrder.setCurrency("人民币");
        payOrder.setChannel("weChat");
        payOrder.setStatus(2);
        payOrder.setChannelStatus(Integer.parseInt(status));
        payOrder.setOrderType(1);
        payOrder.setSource(3);
        payOrder.setClientIp(userId);
        payOrder.setBuyId(userId);
        System.out.println(payOrder);
        int i = orderService.insertPayOrder(payOrder);
        System.out.println("支付表新增数据成功");

        //日志表
        PayOrderRecord payOrderRecord = new PayOrderRecord();
        payOrderRecord.setOrderNo(orderNo);

        if (status.equals("20")){
            payOrderRecord.setType("PAY");
            payOrderRecord.setFromStatus("0");
            payOrderRecord.setToStatus("已支付");
        }else if (status.equals("10")){
            payOrderRecord.setType("REFUND");
            payOrderRecord.setFromStatus("0");
            payOrderRecord.setToStatus("未支付");
        }

        payOrderRecord.setPaidAmount(Integer.parseInt(price));
        payOrderRecord.setCreatedBy(userId.toString());
        int i2 = orderService.insertPayOrderRecord(payOrderRecord);


        //修改用户订单表状态
        QueryWrapper<UserCourseOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.eq("order_no", orderNo);

        UserCourseOrder order = new UserCourseOrder();
        order.setStatus(status);
        int update = orderService.updateUserCourseOrder(order, wrapper);

        ResponseDTO<UserCourseOrder> responseDTO = new ResponseDTO<>();
        responseDTO.setState(200);
        responseDTO.setMessage("更新订单状态成功");
        return responseDTO;
    }

    /**
     * 取消订单
     * @param orderNo
     * @return
     */
    @GetMapping("deleteOrder")
    public ResponseDTO<UserCourseOrder> deleteOrder(@RequestParam("orderno")String orderNo) {
        System.out.println("==============取消订单====================");
        //日志表
        PayOrderRecord payOrderRecord = new PayOrderRecord();
        payOrderRecord.setOrderNo(orderNo);
        payOrderRecord.setType("REFUND");
        payOrderRecord.setFromStatus("0");
        payOrderRecord.setToStatus("已取消");
        payOrderRecord.setCreatedBy("0");
        int i2 = orderService.insertPayOrderRecord(payOrderRecord);

        //修改支付订单表状态
        PayOrder payOrder = new PayOrder();
        payOrder.setStatus(3);
        payOrder.setOrderNo(orderNo);

        int i = orderService.updatePayOrder(payOrder);

        //修改用户订单表状态
        QueryWrapper<UserCourseOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("order_no", orderNo);


        int i1 = orderService.deleteOrder(orderNo);

        ResponseDTO<UserCourseOrder> responseDTO = new ResponseDTO<>();
        responseDTO.setMessage("取消订单成功");
        responseDTO.setState(200);
        return responseDTO;
    }

    /**
     * 查询当前用户购买过的全部课程
     * @param userId
     * @return
     */
    @GetMapping("getOKOrderCourseIds/{userId}")
    public ResponseDTO<List<String>> getOKOrderCourseIds(@PathVariable("userId")Integer userId) {
        List<PayOrder> payOrders = orderService.selectByUserId(userId);
        List<String> ids = new ArrayList<>();
        for (int i = 0; i < payOrders.size(); i++) {
            ids.add(payOrders.get(i).getProductId());
        }
        System.out.println("=========================================================");
        System.out.println(ids);
        ResponseDTO<List<String>> responseDTO = new ResponseDTO<>();
        responseDTO.setContent(ids);
        return responseDTO;
    }


}
